home *** CD-ROM | disk | FTP | other *** search
- *************************
- * HappyENV-Handler *
- * 1.0 05.06.97 *
- * (C) Martin Gierich *
- *************************
-
- * MM's fixes:
-
- * 1.0a
- *
- * - fixed ACTION_SET_FILE_SIZE packet
- * - fixed ACTION_SAME_LOCK packet (circular entry error)
- * - fixed NULL lock (ENVARC: assigned to root)
- * - added ROMTAG structure
- * - support for KS 1.3 removed
- * - startup parms for resident operation are hardcoded into data section
- * - workaround for some dependencies in notification support; noti is a real
- * mess in AmigaOS
-
- * 1.3
- *
- * - added support for date
- * - fixed ACTION_COPY_DIR with ZERO lock
- * - removed hidden files mechanism
- * - increased max path to 255 chars
- * - cleaned up startup/die routines
- * - fixed nasty bug in CalcFullName routine
- * - fixed assigns
- * - added protection bits (lowest byte only)
-
-
- * Do not use this source code or parts of it in other programs !
- * See documentation about Copyright&Disclaimer.
- * Sorry about the not so well commented source.
-
-
- * Switches for options, enabled if label is defined,
- * disabled if semicolon is put in front of it.
-
- ;DEBUG = 1 ;allow debugging output via sushi (RawPutChar)
- ;VERBOSE = 1 ;verbose debug output
- ;EXPAND = 1
-
- ;test=1 set for test, non-public versions
- ;rom=1 set if build for 3.x-like ROM image (TaggedOpen)
-
- mc68000
-
- fdate macro
- dc.b '27.6.2002'
- endm
- $VER macro
- dc.b '1.3'
- endm
-
- include lvos
- INCLUDE dos/dosextens.i
- INCLUDE dos/dostags.i
- include exec/memory.i
- include exec/tasks.i
- include exec/ports.i
- include exec/semaphores.i
- include exec/resident.i
- INCLUDE dos/filehandler.i
- INCLUDE dos/notify.i
- INCLUDE dos/rdargs.i
- ifd DEBUG
- INCLUDE DH1:Actual/Trashcan/HappyENV/Source/debug.i
- endc
-
- * other macros
- * compare both operands and store minimum in the right one
- * third argument is label name
-
- MIN MACRO
- cmp.l \2,\1
- bhs.s .\3
- move.l \1,\2
- .\3
- ENDM
-
- * miscellaneous definitions
-
- LF = 10
- MAXNAME = 36 (32 + terminating 0 + longword alignment)
- MAXPATH = 256-MAXNAME
- BLOCKSIZE = 5000
-
- IFND DEBUG
- DBUG5 MACRO
- ENDM
- DBUG4 MACRO
- ENDM
- DBUG3 MACRO
- ENDM
- DBUG2 MACRO
- ENDM
- DBUG1 MACRO
- ENDM
- DBUG0 MACRO
- ENDM
- ENDC
-
- * EasyRequest structure (Intuition)
- RSRESET
- es_StructSize RS.L 1
- es_Flags RS.L 1
- es_Title RS.L 1
- es_TextFormat RS.L 1
- es_GadgetFormat RS.L 1
- es_SIZEOF RS.W 0
-
-
- * notify list node structure
- RSRESET
- myn_Link RS.L 1
- myn_Request RS.L 1 ;notify-request
- myn_Key RS.L 1 ;pointer to file
- myn_Name RS.B 0 ;path/file name (dynamic)
-
- * lock structure for Lock() and open files
-
- * when changing anything here, remember to fix CreateLock! -MM
-
- RSRESET
- myl_Link RS.L 1
- myl_Key RS.L 1
- myl_Access RS.L 1
- myl_Task RS.L 1
- myl_Volume RS.L 1
- myl_Pos RS.L 1 ;position in file (read/write)
- myl_Data RS.L 1 ;start of file data (read)
- myl_Start RS.L 1 ;start of block list (write)
- myl_Block RS.L 1 ;current block (write)
- myl_BlockPos RS.L 1 ;position in current block (write)
- myl_Size RS.L 1 ;size of file
- myl_Mode RS.B 1 ;0=simple lock, -1=write, 1=read
- myl_Pad RS.B 1
- myl_SIZEOF RS.W 0
-
- * structure for file or dir
- RSRESET
- myf_Link RS.L 1 ;next file/dir
- myf_Parent RS.L 1 ;parent dir (root: 0)
- myf_First RS.L 0 ;dir: points to first entry
- myf_Size RS.L 1 ;file: size of filedata
- myf_Date rs.l 3 ;datestamp
- myf_Attrs rs.b 1 ;attributes
- myf_Type RS.B 1 ;bit7: dir/file, [6:hidden (removed -MM)],
- ;5:copied, 4:notify, 3:modified
- myf_Locks RS.B 1 ;number of locks, -1=write lock
- myf_DataOffs RS.B 1 ;offset to start of data
- myf_Name RS.B 0 ;name (dynamic), then data
-
- * private main structure
- RSRESET
- CharTable RS.B 256
- ExecBase rs.l 1
- DosBase RS.L 1
- IntuiBase RS.L 1
- MyProcess RS.L 1
- MyMsgPort RS.L 1
- MyMemPool RS.L 1
- MyDeviceNode RS.L 1
- MyVolumeBPTR RS.L 1
- NotifyList RS.L 1
- ;Copyfrom RS.L 1
- ;CopyfromLock RS.L 1
- ;CopyfromPort RS.L 1
- ;EnvarcLock rs.l 1
- RootLock RS.L 1
- NotifyPort RS.l 1
- PacketPort RS.l 1
- MyPacket RS.B sp_SIZEOF ;68
- VolumeNode RS.B DevList_SIZEOF ;44
- FileSize RS.L 1
- TotalSize RS.L 1
- NumLocks RS.L 1
-
- ReqStruct RS.B es_SIZEOF ;20
- FormatArgs RS.L 2
-
- *------- DO NOT REARRANGE -----------
- StupVolname RS.L 1
- StupIcon RS.l 1
- StupNocopy RS.l 1
- StupNoreq RS.l 1
- StupExpand RS.l 1
- *------- DO NOT REARRANGE -----------
-
- DosPort rs.l 1
- MyMsg rs.b MN_SIZE+8 ;28
- MyFIB rs.b fib_SIZEOF ;260
- MyFH rs.b fh_SIZEOF ;44
- MyML rs.b MLH_SIZE ;12
-
- RootDir RS.B myf_Name+MAXNAME ;28+36=64
-
- *------- DO NOT REARRANGE -----------
- TempPath RS.B MAXPATH ;256-36
- TempName RS.B MAXNAME ;36
- *------- DO NOT REARRANGE -----------
-
- VolumeName RS.B MAXNAME ;36
-
- WriteProtected RS.B 1
- My_SIZEOF RS.L 0
-
- MyPkt = MyPacket+sp_Pkt
-
- *******************************************************
-
- *******************************************************
-
- * common register usage:
- * a4=DOSpacket
- * a5=private struct
- * a6=execbase
-
- start: movem.l d2-d7/a2-a6,-(sp) ;do some basic inits
- move.l 4.w,a6
- suba.l a1,a1
- sys FindTask
- movea.l d0,a2
- ; bset #0,(pr_Flags+1,a2) ;unload seglist upon expunge
- lea (pr_MsgPort,a2),a3
- movea.l a3,a0
- sys WaitPort
- movea.l a3,a0
- sys GetMsg ;get startup message
- movea.l d0,a4
- movea.l (sp_Msg+MN+LN_NAME,a4),a4
- clr.l (dp_Res1,a4)
- move.l #ERROR_NO_FREE_STORE,(dp_Res2,a4)
- move.l dp_Arg3(a4),d7
- lsl.l #2,d7
- movea.l d7,a0
- clr.l (dn_Task,a0) ;will restart the handler on failure
- move.l #My_SIZEOF,d0
- move.l #MEMF_CLEAR|MEMF_PUBLIC,d1
- sys AllocVec
- tst.l d0
- beq exit1
- movea.l d0,a5
- DBUG1 txstart,a5
- move.l a6,(ExecBase,a5)
- move.l a2,MyProcess(a5)
- move.l a3,MyMsgPort(a5)
-
- IFD rom
- moveq #OLTAG_DOS,d0
- sys TaggedOpenLibrary
- ELSE
- lea dosname(pc),a1
- moveq #37,d0
- sys OpenLibrary
- ENDC
-
- move.l d0,DosBase(a5)
- beq exit2
- lea (RootDir,a5),a1
- bsr SetCurrentDate
-
- IFND rom
- cmp.w #39,(LIB_VERSION,a6)
- bcs .OS20
- ENDC
-
- moveq #1,d0
- move.l #5000,d1
- move.l #2000,d2
- sys CreatePool
- move.l d0,MyMemPool(a5)
- .OS20 lea (MyML,a5),a0
- NEWLIST a0
- move.l d7,MyDeviceNode(a5)
- movea.l d7,a0
- movea.l dn_Name(a0),a0
- lea RootDir+myf_Name(a5),a1
- moveq #6,d0
- bsr CopyBSTR2Char
-
- IFND rom
- lea intuiname(pc),a1 ;init "unknown packet" requester
- moveq #36,d0
- sys OpenLibrary
- move.l d0,IntuiBase(a5)
- beq.s .A
- lea ReqStruct(a5),a0
- moveq #es_SIZEOF,d0
- move.l d0,(es_StructSize,a0)
- lea reqtitle(pc),a1
- move.l a1,(es_TextFormat,a0)
- lea reqbutton(pc),a1
- move.l a1,(es_GadgetFormat,a0)
- .A moveq #0,d2
-
- args: move.l DosBase(a5),a6
- move.l MyDeviceNode(a5),a1
- move.l dn_Startup(a1),d3
- beq .A
- clr.l dn_Startup(a1)
- movea.l d3,a0
- lea TempPath(a5),a1
- move.l a1,a2
- move.l #MAXPATH-1,d0
- bsr CopyBSTR2Char
- moveq #DOS_RDARGS,d1
- ; moveq #0,d2
- sys AllocDosObject
- move.l d0,d3
- beq .A
- move.l a2,a0
- .D move.b (a0)+,d0
- beq.s .C
- cmp.b #"_",d0
- bne.s .D
- move.b #" ",-1(a0)
- bra.s .D
- .C move.b #LF,-1(a0)
- clr.b (a0)
- sub.l a2,a0
- lea (StupVolname,a5),a3
- move.l a3,d2 ;Argument-Array
- move.l d3,a1 ;Rd-Args-Struct
- move.l a2,(a1)+ ;CSource.Buffer
- move.l a0,(a1) ;CSource.Length
- lea template(pc),a0
- move.l a0,d1 ;Template
- sys ReadArgs ;process Startup line
- DBUG4 txargs,(a3),4(a3),8(a3),12(a3)
- move.l d0,d2
- bne.s .E
-
- * Display requester for bad startup arguments
-
- move.l IntuiBase(a5),d0
- beq.s .A
- lea ReqStruct(a5),a1
- lea reqreadargs(pc),a0
- move.l a0,(es_TextFormat,a1)
- sub.l a2,a2
- sub.l a3,a3
- sub.l a0,a0
- movea.l d0,a6
- sys EasyRequestArgs
- movea.l DosBase(a5),a6
- bra.s .A
-
- .E movea.l (a3)+,a0
- move.l a0,d0
- bne.s .F
- ENDC
-
- .A lea volname1(pc),a0
-
- IFND rom
- tst.l StupIcon(a5)
- beq.s .F
- lea volname2(pc),a0
- ENDC
-
- .F lea VolumeName(a5),a1
- moveq #MAXNAME-2,d0
- bsr CopyChar2BSTR
- move.l d0,d4
-
- IFND rom
- move.l d2,d1
- sys FreeArgs
- moveq #DOS_RDARGS,d1
- move.l d3,d2
- beq .B
- sys FreeDosObject
- ENDC
-
- .B move.l d4,(StupVolname,a5)
- movea.l (ExecBase,a5),a6
-
- upconv: bsr InitConversion ;init upper case table
- sys CreateMsgPort
- move.l d0,(NotifyPort,a5)
- beq exit3
-
- IFND rom
- tst.l StupNocopy(a5)
- bne nocopy
- ENDC
-
- sys CreateMsgPort
- move.l d0,(PacketPort,a5)
- beq exit4
- move.l d0,d6
- clr.l -(sp)
- pea (procn,pc)
- move.l #NP_Name,-(sp)
- pea (procc,pc)
- move.l #NP_Entry,-(sp)
- movea.l (DosBase,a5),a6
- move.l sp,d1
- sys CreateNewProc
- movea.l (ExecBase,a5),a6
- lea (20,sp),sp
- tst.l d0
- beq exit5
- movea.l d0,a2
-
- movea.l a2,a1
- move.l a5,(TC_Userdata,a2) ;stuff our data area to userdata
- move.l #SIGBREAKF_CTRL_F,d0 ;let's use CTRL-F for signalling
- sys Signal ;we're done
-
- movea.l d6,a0
- moveq #1,d0
- move.b (MP_SIGBIT,a0),d1
- lsl.l d1,d0
- sys Wait
-
- lea (MyMsg,a5),a0 ;init message
- moveq #MN_SIZE+8,d0
- move.w d0,(MN_LENGTH,a0)
- moveq #NT_MESSAGE,d0
- move.b d0,(LN_TYPE,a0)
- move.l d6,(MN_REPLYPORT,a0)
-
- nocopy: lea RootDir(a5),a2 ;create Lock for DiskInfo
- moveq #ACCESS_READ,d2
- bsr CreateLock
- move.l d0,RootLock(a5)
- beq exit6
-
- volnod: lea VolumeNode(a5),a2 ;set up volume node
- move.l a2,d0
- lsr.l #2,d0
- move.l d0,MyVolumeBPTR(a5)
- moveq #DLT_VOLUME,d0
- move.l d0,dl_Type(a2)
- move.l MyMsgPort(a5),dl_Task(a2)
- move.l #"DOS"<<8,dl_DiskType(a2)
- move.l (StupVolname,a5),(dl_Name,a2)
- lea (dl_VolumeDate,a2),a0
- move.l a0,d1
- movea.l (DosBase,a5),a6
- sys DateStamp
-
- IFND rom
- tst.l StupIcon(a5)
- beq.s .D
- moveq #LDF_VOLUMES|LDF_WRITE,d1
- sys AttemptLockDosList
- andi.l #~1,d0
- beq exit7
- move.l a2,d1
- sys AddDosEntry
- move.l d0,d2
- moveq #LDF_VOLUMES|LDF_WRITE,d1
- sys UnLockDosList
- tst.l d2
- beq exit7
- ENDC
-
- .D movea.l d7,a0 ;DeviceNode
- move.l (MyMsgPort,a5),(dn_Task,a0)
- moveq #DOSTRUE,d2 ;init ok: reply startup packet
- moveq #0,d3
- move.l a4,d1
- sys ReplyPkt
-
- loop: sys WaitPkt
- movea.l d0,a4
- clr.l (dp_Res1,a4)
- clr.l (dp_Res2,a4)
-
- * Handle replies of Notify messages
- GetNotify:
- \A movea.l NotifyPort(a5),a0
- movea.l (ExecBase,a5),a6
- sys GetMsg
- tst.l d0
- beq.s \E
- move.l d0,a1
- DBUG1 txgnoti,a1
- ; move.l nm_NReq(a1),a0
- ; subq.l #1,nr_MsgCount(a0)
- moveq #NotifyMessage_SIZEOF,d0
- bsr FreeMem
- bra.s \A
-
- \E move.l dp_Type(a4),d0
-
- IFD DEBUG
- move.l dp_Port(a4),a1
- move.l MP_SIGTASK(a1),a1
- move.l LN_NAME(a1),a1
- DBUG5 txpack,d0,dp_Arg1(a4),dp_Arg2(a4),dp_Arg3(a4),a1
- ENDC
-
- move.l d0,d1
- swap d1
- tst.w d1
- bne.s .A
- lea start(pc),a1
- lea JumpTable(pc),a2
- moveq #0,d2
- .C move.w (a2)+,d1
- bpl.s .E
- .A DBUG1 txerr1,d0
- IFND rom
- bsr RequestUnknown
- ENDC
- move.w #ERROR_ACTION_NOT_KNOWN,(dp_Res2+2,a4)
- bra.s .D
-
- .E move.w (a2)+,d2
- cmp.w d0,d1
- bne.s .C
- add.l d2,a1
- ;***
-
- * packets must preserve a5/a4; all others may be trashed
-
- jsr (a1) ;jump into subroutine to process packet
- ;***
- .D
- IFD DEBUG
- moveq #DOSTRUE,d0
- cmp.l dp_Res1(a4),d0
- beq.s .\@H
- DBUG2 txres,dp_Res1(a4),dp_Res2(a4)
- .\@H ENDC
-
- _rp movea.l (DosBase,a5),a6
- _rp1 move.l (dp_Res1,a4),d2
- move.l (dp_Res2,a4),d3
- move.l a4,d1
- sys ReplyPkt
- bra loop
-
- ADie: addq.l #4,sp ;exit routine
-
- move.w #ERROR_OBJECT_IN_USE,(dp_Res2+2,a4)
- move.l NumLocks(a5),d0
- subq.l #1,d0
- bne _rp
- tst.l (NotifyList,a5)
- bne _rp
-
- IFND rom
- tst.l StupIcon(a5)
- beq .A
- movea.l (DosBase,a5),a6
- moveq #LDF_DEVICES|LDF_VOLUMES|LDF_WRITE,d1
- sys AttemptLockDosList
- andi.l #~1,d0
- beq _rp1
- lea (VolumeNode,a5),a0
- move.l a0,d1
- sys RemDosEntry
- move.l d0,d2
- beq .B
- move.l (MyDeviceNode,a5),d1
- sys RemDosEntry
- .B moveq #LDF_DEVICES|LDF_VOLUMES|LDF_WRITE,d1
- sys UnLockDosList
- tst.l d2
- beq _rp1
- movea.l (ExecBase,a5),a6
- ENDC
- .A
-
- * Reply all packets that are waiting to be processed (for exit)
- FlushPackets:
- .A move.l MyMsgPort(a5),a0
- sys GetMsg
- tst.l d0
- beq .exit
- move.l d0,a1
- move.l (MN+LN_NAME,a1),d0
- beq.s .A
- movea.l d0,a0
- clr.l (dp_Res1,a0)
- move.l #ERROR_ACTION_NOT_KNOWN,(dp_Res2,a0)
- clr.l (dp_Port,a0)
- sys ReplyMsg
- bra.s .A
-
- .exit moveq #DOSTRUE,d0
- move.l d0,(dp_Res1,a4)
- move.l MyDeviceNode(a5),a0
- clr.l dn_Task(a0)
- clr.l (MyMsgPort,a5)
- exit7: movea.l (ExecBase,a5),a6
- move.l RootLock(a5),a1
- bsr FreeLock
- exit6:
- IFND rom
- tst.l StupNocopy(a5)
- bne exit4
- ENDC
-
- lea (MyMsg,a5),a1
- clr.l (MN_SIZE,a1) ;=QUIT
- movea.l (DosPort,a5),a0
- sys PutMsg
- movea.l (PacketPort,a5),a0
- sys WaitPort
- exit5: movea.l (PacketPort,a5),a0
- sys DeleteMsgPort
- exit4: movea.l (NotifyPort,a5),a0
- sys DeleteMsgPort
- exit3: move.l DosBase(a5),a1
- sys CloseLibrary
- DBUG3 txend,FileSize(a5),TotalSize(a5),NumLocks(a5)
- move.l MyMemPool(a5),d0
- beq.s .A
- move.l d0,a0
- sys DeletePool
- .A lea (MyML,a5),a2
- .C IFEMPTY a2,exit2
- SUCC a2,a1
- bsr _free
- bra .C
-
- exit2: movea.l (MyMsgPort,a5),a3
- move.l a5,a1
- sys FreeVec
- exit1: movea.l (dp_Link,a4),a1
- movea.l (dp_Port,a4),a0
- move.l a3,(dp_Port,a4)
- clr.l (MN,a1)
- clr.l (MN+LN_PRED,a1)
- sys PutMsg ;reply startup/die message
- movem.l (sp)+,d2-d7/a2-a6
- moveq #0,d0
- rts
-
- *******************************************************
-
- * table for branching from main to subroutine depending on the
- * current packet
-
- JumpTable:
- dc.w ACTION_NIL,NoAction-start
- dc.w ACTION_SET_PROTECT,ASetProtect-start
- dc.w ACTION_SET_COMMENT,Unsupported-start
- dc.w ACTION_SET_DATE,ASetDate-start
- dc.w ACTION_INHIBIT,Unsupported-start
- dc.w ACTION_FLUSH,NoAction-start
- dc.w ACTION_IS_FILESYSTEM,NoAction-start
-
- dc.w ACTION_DIE,ADie-start
- dc.w ACTION_CURRENT_VOLUME,ACurrentVolume-start
- dc.w ACTION_RENAME_DISK,ARenameDisk-start
- dc.w ACTION_WRITE_PROTECT,AWriteProtect-start
-
- dc.w ACTION_FINDUPDATE,AOpenReadWrite-start
- dc.w ACTION_FINDINPUT,AOpenOldfile-start
- dc.w ACTION_FINDOUTPUT,AOpenNewfile-start
- dc.w ACTION_END,ACloseFile-start
- dc.w ACTION_SEEK,ASeekPosition-start
- dc.w ACTION_READ,AReadFile-start
- dc.w ACTION_WRITE,AWriteFile-start
- dc.w ACTION_DELETE_OBJECT,ADeleteObject-start
- dc.w ACTION_RENAME_OBJECT,ARenameObject-start
- dc.w ACTION_CREATE_DIR,ACreateDir-start
-
- dc.w ACTION_LOCATE_OBJECT,ALocateObject-start
- dc.w ACTION_PARENT,AParentDir-start
- dc.w ACTION_COPY_DIR,ADuplicateLock-start
- dc.w ACTION_FREE_LOCK,AFreeLock-start
- dc.w ACTION_SAME_LOCK,ASameLock-start
- dc.w ACTION_EXAMINE_OBJECT,AExamineObject-start
- dc.w ACTION_EXAMINE_ALL,Unsupported-start
- dc.w ACTION_EXAMINE_FH,AExamineFH-start
- dc.w ACTION_EXAMINE_ALL_END,Unsupported-start
- dc.w ACTION_EXAMINE_NEXT,AExamineNext-start
- dc.w ACTION_DISK_INFO,ADiskInfo1-start
- dc.w ACTION_INFO,ADiskInfo2-start
-
- dc.w ACTION_ADD_NOTIFY,AAddNotify-start
- dc.w ACTION_REMOVE_NOTIFY,ARemoveNotify-start
- dc.w ACTION_SET_FILE_SIZE,ASetFileSize-start
- dc.w ACTION_FH_FROM_LOCK,AFHfromLock-start
- dc.w ACTION_CHANGE_MODE,AChangeMode-start
- dc.w ACTION_COPY_DIR_FH,ADupLockFromFH-start
- dc.w ACTION_PARENT_FH,AParentFromFH-start
- dc.w -1
-
-
- * strings
-
- volname1 dc.b "Env",0
- reqtitle dc.b "HappyENV warning:",0
- procn dc.b 'HappyENV DOS-process',0
- requnknown dc.b "Task %s",LF,"uses packet %ld",0
- reqbutton dc.b "OK",0
-
- IFND rom
- intuiname dc.b "intuition.library",0
- dosname dc.b "dos.library",0
- utilname dc.b "utility.library",0
- _expn dc.b 'expansion.library',0
- reqreadargs dc.b "Bad startup arguments",0
- template dc.b "VOLNAME/K,ICON/S,NOCOPY/S,NOREQ/S",0
- volname2 dc.b "Environment",0
- ENDC
-
- envarc dc.b 'ENVARC:',0
-
- IFD EXPAND
- prefstx dc.b "prefs",0
- configtx dc.b "config",0
- ENDC
-
- even
-
- *******************************************************
-
- * Init to-upper-conversion table which allows
- * quick case independent compares
- InitConversion:
- lea CharTable(a5),a2
- move.w #255,d2
- move.w d2,d0
- .A move.b d0,0(a2,d0.w)
- dbra d0,.A
- moveq #"A",d0
- .C move.b d0,"a"-"A"(a2,d0.w)
- addq.w #1,d0
- cmp.b #"Z"+1,d0
- bne.s .C
- move.w #192,d0
- .F move.b d0,224-192(a2,d0.w)
- addq.w #1,d0
- cmp.b #222+1,d0
- bne.s .F
-
- IFD rom
- moveq #OLTAG_UTILITY,d0
- sys TaggedOpenLibrary
- ELSE
- lea utilname(pc),a1 ;open utility.library
- moveq #37,d0
- sys OpenLibrary
- ENDC
-
- tst.l d0
- beq.s .D
- move.l d0,a6
- .E move.w d2,d0
- sys ToUpper
- move.b d0,0(a2,d2.w)
- dbra d2,.E
- move.l a6,a1
- move.l (ExecBase,a5),a6
- sys CloseLibrary
- .D rts
-
- * Display requester for unknown packets
-
- IFND rom
- RequestUnknown:
- tst.l StupNoreq(a5)
- bne.s .A
- move.l IntuiBase(a5),d0
- beq.s .A
- movea.l d0,a6
- lea ReqStruct(a5),a1
- lea requnknown(pc),a0
- move.l a0,(es_TextFormat,a1)
- sub.l a2,a2
- lea FormatArgs(a5),a3
- move.l dp_Type(a4),4(a3)
- move.l dp_Port(a4),a0
- move.l MP_SIGTASK(a0),a0
- move.l LN_NAME(a0),(a3)
- sub.l a0,a0
- sys EasyRequestArgs
- move.l (ExecBase,a5),a6
- .A rts
- ENDC
-
- *******************************************************
-
- *******************************************************
-
-
- * Following there are all subroutines to process the individual packets
- * It starts with some general purpose and Filehandle handling ones.
-
- * No action will be performed
- NoAction:
- moveq #DOSTRUE,d0
- move.l d0,dp_Res1(a4)
- rts
-
- ACurrentVolume:
- move.l MyVolumeBPTR(a5),dp_Res1(a4)
- bra NoAction
-
- * For unsupported packets without showing a requester
- Unsupported:
- DBUG1 txerr1,dp_Type(a4)
- move.w #ERROR_ACTION_NOT_KNOWN,(dp_Res2+2,a4)
- _ret1 rts
-
-
- ARenameDisk:
- move.w #ERROR_DISK_WRITE_PROTECTED,(dp_Res2+2,a4)
- tst.b WriteProtected(a5)
- bne _ret1
- move.l dp_Arg1(a4),a0
- lea TempName(a5),a1
- moveq #MAXNAME-2,d0
- bsr CopyBSTR2Char
- lea TempName(a5),a0
- lea VolumeName(a5),a1
- moveq #MAXNAME-2,d0
- bsr CopyChar2BSTR
- bra NoAction
-
- AWriteProtect:
- move.l dp_Arg1(a4),d0
- move.b d0,WriteProtected(a5)
- bra NoAction
-
- AOpenOldfile:
- move.l dp_Arg3(a4),a0
- move.l dp_Arg2(a4),d0
- moveq #ACCESS_READ,d2
- bsr LocateObject
- OpnOld: move.l dp_Arg1(a4),a3 ;label used by AOpenReadWrite and AFHFromLock
- add.l a3,a3
- add.l a3,a3
- clr.l fh_Interactive(a3)
- move.l d0,fh_Arg1(a3)
- beq _ret2
- move.l d0,a0
- move.l myl_Key(a0),a1
- move.w #ERROR_OBJECT_WRONG_TYPE,(dp_Res2+2,a4)
- tst.b myf_Type(a1) ;do not open dirs
- bmi.s .A
- move.l a0,a1
- bsr FreeLock
- bra _ret2
- .A move.l myf_Size(a1),myl_Size(a0)
- moveq #0,d0
- move.b myf_DataOffs(a1),d0
- add.l d0,a1
- move.l a1,myl_Data(a0)
- move.b #1,myl_Mode(a0)
- DBUG1 txopeno,fh_Arg1(a3)
- bra NoAction
-
- AOpenReadWrite:
- move.l dp_Arg3(a4),a0
- move.l dp_Arg2(a4),d0
- moveq #ACCESS_READ,d2
- bsr LocateObject
- bne.s OpnOld
-
- AOpenNewfile:
- move.w #ERROR_DISK_WRITE_PROTECTED,(dp_Res2+2,a4)
- tst.b WriteProtected(a5)
- bne _ret2
- move.w #ERROR_OBJECT_EXISTS,(dp_Res2+2,a4)
- move.l dp_Arg1(a4),a3
- add.l a3,a3
- add.l a3,a3
- clr.l fh_Interactive(a3)
- move.l dp_Arg2(a4),d0 ;does file already exist ?
- move.l dp_Arg3(a4),a0
- bsr SearchObject
- beq.s .A
- move.l d0,a1
- tst.b myf_Type(a1) ;do not overwrite dirs
- bpl _ret2
- move.w #ERROR_DELETE_PROTECTED,(dp_Res2+2,a4)
- btst #FIBB_DELETE,(myf_Attrs,a1)
- bne _ret2
- move.w #ERROR_WRITE_PROTECTED,(dp_Res2+2,a4)
- btst #FIBB_WRITE,(myf_Attrs,a1)
- bne _ret2
- move.l (myf_Parent,a1),-(sp)
- bsr DeleteObject
- movea.l (sp)+,a1
- beq _ret2
- bsr SetCurrentDate ;update parent date
- .A bsr SplitPath
- move.w #ERROR_DIR_NOT_FOUND,(dp_Res2+2,a4)
- move.l dp_Arg2(a4),d0
- bsr CreatePath
- beq _ret2
- move.l a3,-(sp)
- move.l d0,a3
- lea TempName(a5),a2
- moveq #0,d2
- bsr CreateNewObject
- move.l (sp)+,a3
- beq.s _ret2
- move.l d0,a2
- moveq #ACCESS_WRITE,d2
- bsr CreateLock
- move.l d0,fh_Arg1(a3)
- beq.s _ret2
- move.l d0,a0
- moveq #DOSTRUE,d0
- move.b d0,myl_Mode(a0)
- move.l d0,dp_Res1(a4)
- bset #3,(myf_Type,a2)
- DBUG1 txopenn,fh_Arg1(a3)
- movea.l (myf_Parent,a2),a1
- bsr SetCurrentDate ;update parent date
- _ret2 rts
-
- ACloseFile:
- move.l dp_Arg1(a4),a1
- tst.b myl_Mode(a1)
- bmi.s .D
- bsr FreeLock
- bra.s .ok
- .D move.l myl_Size(a1),d2
- move.l myl_Key(a1),a2
- move.l myf_Parent(a2),a3
- lea myf_Name(a2),a2
- bsr CreateNewObject
- beq.s _ret2
- move.l d0,d4
- move.l d0,a3
- add.l d1,a3
- move.l dp_Arg1(a4),a2
- bsr CopyBlocksToMem
- move.l a2,a1
- move.l myl_Key(a2),a2
- bsr FreeLock
- moveq #3,d0
- btst d0,(myf_Type,a2) ;file has been modified?
- beq .unset
- movea.l d4,a1
- bset d0,(myf_Type,a1)
- bclr #FIBB_ARCHIVE,(myf_Type,a1)
- bsr SetCurrentDate ;update object date
- movea.l d4,a1
- movea.l (myl_Key,a1),a0
- bclr #FIBB_ARCHIVE,(myf_Type,a0)
- movea.l (myf_Parent,a1),a1
- bsr SetCurrentDate ;update parent date
- .unset move.l a2,a1
- bsr DeleteObj
- beq.s _ret2
- move.l d4,a0
- bsr CheckNotify
- .ok bra NoAction
-
- * Copy all blocks of a filehandle to memory
- * ENTRY: a2=lock, a3=destination memory
- * EXIT: nothing (some registers changed)
- * USED BY: ACloseFile, ASetFileSize
- CopyBlocksToMem:
- move.l myl_Start(a2),d3
- .F tst.l d3
- beq _ret2
- move.l d3,-(sp)
- move.l d3,a0
- move.l (a0)+,d3
- move.l (a0)+,d2
- move.l a3,a1
- move.l d2,d0
- sys CopyMem
- add.l d2,a3
- move.l d2,d0
- addq.l #8,d0
- move.l (sp)+,a1
- bsr FreeMem
- bra.s .F
-
- AWriteFile:
- moveq #-1,d0
- move.l d0,dp_Res1(a4)
- move.w #ERROR_DISK_WRITE_PROTECTED,(dp_Res2+2,a4)
- tst.b WriteProtected(a5)
- bne .fail
- move.l dp_Arg1(a4),a2 ;lock
- movea.l (myl_Key,a2),a0
- move.w #ERROR_WRITE_PROTECTED,(dp_Res2+2,a4)
- btst #FIBB_WRITE,(myf_Attrs,a0)
- bne .fail
- move.l dp_Arg2(a4),a3 ;buffer
- move.l dp_Arg3(a4),d3 ;length
- bsr ReadToWriteMode
- beq .fail
- .F move.l d3,d2
- move.l myl_Block(a2),d0
- beq.s .E
- move.l d0,a1
- move.l 4(a1),d0
- sub.l myl_BlockPos(a2),d0
- beq.s .C
- bmi.s .C
- MIN d0,d2,G
- .D addq.l #8,a1
- add.l myl_BlockPos(a2),a1
- move.l a3,a0
- move.l d2,d0
- sys CopyMem
- DBUG2 txwins,d2,myl_Pos(a2)
- add.l d2,a3
- add.l d2,myl_Pos(a2)
- add.l d2,myl_BlockPos(a2)
- sub.l d2,d3
- beq.s .ok
- bra.s .F
-
- .C move.l (a1),d0
- beq.s .E
- move.l d0,myl_Block(a2)
- clr.l myl_BlockPos(a2)
- bra.s .F
-
- .E bsr AppendNewBlock
- beq.s .fail
- clr.w (dp_Res2+2,a4)
- move.l a3,a0
- move.l d3,d0
- sys CopyMem
- add.l d3,myl_Pos(a2)
- move.l d3,myl_BlockPos(a2)
- .ok move.l dp_Arg3(a4),dp_Res1(a4) ;zero length writes are skipped
- beq .fail
- movea.l (myl_Key,a2),a1
- bset #3,(myf_Type,a1) ;notification attention
- DBUG3 txwrite,dp_Arg3(a4),myl_Pos(a2),myl_Size(a2)
- .fail rts
-
- ASetFileSize:
- moveq #DOSTRUE,d0
- move.l d0,dp_Res1(a4)
- move.w #ERROR_DISK_WRITE_PROTECTED,(dp_Res2+2,a4)
- tst.b WriteProtected(a5)
- bne .fail
- move.l dp_Arg1(a4),a2 ;a2=lock
- movea.l (myl_Key,a2),a0
- move.w #ERROR_WRITE_PROTECTED,(dp_Res2+2,a4)
- btst #FIBB_WRITE,(myf_Attrs,a0)
- bne .fail
- move.w #ERROR_SEEK_ERROR,(dp_Res2+2,a4)
- move.l dp_Arg2(a4),d3 ;d3=position to truncate
- move.l dp_Arg3(a4),d2 ;d2=mode
- move.l myl_Size(a2),d4 ;d4=old size
- ; moveq #OFFSET_BEGINNING,d0
- cmp.l d0,d2
- beq.s .E
- moveq #OFFSET_END,d0
- cmp.l d0,d2
- bne.s .C
- add.l d4,d3
- bra.s .E
-
- .C tst.l d2
- bne .fail
- add.l myl_Pos(a2),d3
- .E DBUG2 txsize,myl_Key(a2),d4,d3
- tst.l d3 ;d3=new size
- bmi .fail
- cmp.l d4,d3
- beq.s .ok ;size will not change
- bhi.s .A ;append some data
-
- move.l d3,myl_Size(a2) ;truncate some data
- MIN d3,myl_Pos(a2),F
- bsr ReadToWriteMode
- beq.s .fail
- cmp.b #1,d0
- beq.s .ok
- move.l myl_Pos(a2),myl_BlockPos(a2)
- move.l d3,d0
- beq.s .D
- bsr CreateNewBlock
- beq.s .fail
- .D move.l myl_Start(a2),d4
- move.l d0,myl_Block(a2)
- move.l d0,myl_Start(a2)
- move.l a1,a3
- .J tst.l d4
- beq.s .ok
- move.l d4,-(sp)
- move.l d4,a0
- move.l (a0)+,d4
- move.l (a0)+,d2
- cmp.l d2,d3
- bls.s .G
- move.l d2,d0
- sub.l d2,d3
- bra.s .H
- .G move.l d3,d0
- beq.s .I
- moveq #0,d3
- .H move.l a3,a1
- sys CopyMem
- .I add.l d2,a3
- move.l d2,d0
- addq.l #8,d0
- move.l (sp)+,a1
- bsr FreeMem
- bra.s .J
-
- .A bsr ReadToWriteMode ;append some data
- beq.s .fail
- sub.l d4,d3
- bsr AppendNewBlock
- beq.s .fail
- .ok move.l myl_Size(a2),dp_Res1(a4)
- beq .fail
- movea.l (myl_Key,a2),a0
- bset #3,(myf_Type,a0) ;notification attention
- .fail rts
-
-
- * Convert Lock from Read to Write mode
- * ENTRY: a2=lock
- * EXIT: d0,Z=success (0=fail, 1=changed, 2=not changed)
- * USED BY: AWriteFile, ASetFileSize
- ReadToWriteMode:
- moveq #2,d0
- tst.b myl_Mode(a2)
- bmi.s .ok
- move.w #ERROR_WRITE_PROTECTED,(dp_Res2+2,a4)
- move.l myl_Key(a2),a0
- move.b myf_Locks(a0),d0
- cmpi.b #-1,d0
- beq .wr
- cmpi.b #1,d0
- bhi.s .fail
- .wr move.l myl_Size(a2),d0
- beq.s .A
- bsr CreateNewBlock
- beq.s .fail
- .A move.l d0,myl_Block(a2)
- move.l d0,myl_Start(a2)
- move.l myl_Pos(a2),myl_BlockPos(a2)
- st myl_Mode(a2)
- move.l myl_Key(a2),a0
- st myf_Locks(a0)
- move.l myl_Data(a2),a0
- move.l myl_Size(a2),d0
- beq.s .C
- sys CopyMem
- .C DBUG2 txchng,myl_Key(a2),myl_Pos(a2),myl_Size(a2)
- moveq #1,d0
- .ok rts
- .fail moveq #0,d0
- rts
-
- * Create and append a new block as last one to block list
- * ENTRY: d3=size, a2=lock
- * EXIT: d0,Z=success, a1=newblock+8
- * USED BY: AWriteFile, ASetFileSize
- AppendNewBlock:
- move.l d3,d0
- bsr CreateNewBlock
- beq.s .fail
- add.l d3,myl_Size(a2)
- move.l myl_Block(a2),a0
- move.l d0,myl_Block(a2)
- move.l a0,d1
- bne.s .A
- lea myl_Start(a2),a0
- .A move.l (a0),d1 ;look for end of blocks
- beq.s .C ; for SetFileSize
- move.l d1,a0
- bra.s .A
- .C move.l d0,(a0) ;insert new block as last
- moveq #1,d0
- .fail rts
-
- * Allocates memory for a new block
- * ENTRY: d0=size
- * EXIT: d0=block , a1=block+8
- * USED BY: AppendNewBlock, ReadToWriteMode, ASetFileSIze
- CreateNewBlock:
- move.w #ERROR_DISK_FULL,(dp_Res2+2,a4)
- move.l d0,-(sp)
- addq.l #8,d0
- bsr AllocMem
- beq.s .fail
- move.l d0,a1
- clr.l (a1)+
- move.l (sp),(a1)+
- .fail addq.l #4,sp
- tst.l d0
- rts
-
- AReadFile:
- move.l dp_Arg1(a4),a2 ;lock
- movea.l (myl_Key,a2),a0
- move.w #ERROR_READ_PROTECTED,(dp_Res2+2,a4)
- btst #FIBB_READ,(myf_Attrs,a0)
- bne .ok
- move.l dp_Arg2(a4),a3 ;buffer
- move.l myl_Size(a2),d0
- move.l myl_Pos(a2),a0
- sub.l a0,d0
- move.l dp_Arg3(a4),d3 ;length
- MIN d0,d3,G
- ; clr.w (dp_Res2+2,a4)
- DBUG3 txread,d3,dp_Arg3(a4),myl_Pos(a2)
- add.l d3,myl_Pos(a2)
- move.l d3,dp_Res1(a4)
- beq.s .ok
- tst.b myl_Mode(a2)
- bpl.s .E
-
- .F move.l d3,d2
- move.l myl_Block(a2),a0
- move.l 4(a0),d0
- sub.l myl_BlockPos(a2),d0
- beq.s .C
- bmi.s .C
- MIN d0,d2,D
- addq.l #8,a0
- add.l myl_BlockPos(a2),a0
- move.l a3,a1
- move.l d2,d0
- sys CopyMem
- add.l d2,a3
- add.l d2,myl_BlockPos(a2)
- sub.l d2,d3
- beq.s .ok
- bra.s .F
- .C move.l (a1),d0
- beq.s .ok
- move.l d0,myl_Block(a2)
- clr.l myl_BlockPos(a2)
- bra .F
-
- .E move.l myl_Data(a2),d0
- add.l d0,a0
- move.l a3,a1
- move.l d3,d0
- sys CopyMem
- .ok rts
-
- ASeekPosition
- move.l dp_Arg1(a4),a2 ;a2=lock
- move.l dp_Arg2(a4),d1 ;d1=position
- move.l dp_Arg3(a4),d2 ;d2=mode
- ; clr.w (dp_Res2+2,a4)
- move.l myl_Pos(a2),d3 ;d3=old pos
- move.l myl_Size(a2),d4 ;d4=size
-
- moveq #OFFSET_BEGINNING,d0
- cmp.l d0,d2
- beq.s .E
- moveq #OFFSET_END,d0
- cmp.l d0,d2
- bne.s .C
- add.l d4,d1
- bra.s .E
- .C moveq #OFFSET_CURRENT,d0
- cmp.l d0,d2
- bne.s .fail
- add.l d3,d1
- .E move.l d1,myl_Pos(a2)
- bmi.s .A
- cmp.l d1,d4
- bhs.s Seeek
- move.l d4,myl_Pos(a2)
- bra.s .fail
- .A clr.l myl_Pos(a2)
- .fail move.w #ERROR_SEEK_ERROR,(dp_Res2+2,a4)
- moveq #-1,d3
-
- Seeek tst.b myl_Mode(a2) ;label not used globally
- bpl.s .A
- move.l myl_Pos(a2),d2
- move.l myl_Start(a2),d0
- beq.s .A
- bra.s .E
- .D move.l (a0),d0
- beq.s .C
- .E move.l d0,a0
- move.l 4(a0),d1
- sub.l d1,d2
- beq.s .F
- bpl.s .D
- .F add.l d1,d2
- .C move.l a0,myl_Block(a2)
- move.l d2,myl_BlockPos(a2)
- .A move.l d3,dp_Res1(a4)
- DBUG1 txseek,myl_Pos(a2)
- _ret3 rts
-
- ADeleteObject:
- move.w #ERROR_DISK_WRITE_PROTECTED,(dp_Res2+2,a4)
- tst.b WriteProtected(a5)
- bne.s _ret3
- move.w #ERROR_OBJECT_NOT_FOUND,(dp_Res2+2,a4)
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a0
- bsr SearchObject
- beq _ret3
- movea.l d0,a0
- move.w #ERROR_DELETE_PROTECTED,(dp_Res2+2,a4)
- btst #FIBB_DELETE,(myf_Attrs,a0)
- bne _ret3
- movem.l d0-d1,-(sp)
- moveq #1,d0
- bsr NotifyObject
- movem.l (sp)+,d0-d1
- move.l d0,a1
- move.l (myf_Parent,a1),-(sp)
- bsr DeleteObject
- movea.l (sp)+,a1
- beq.s _ret3
- bsr SetCurrentDate
- bra NoAction
-
- ARenameObject:
- move.w #ERROR_DISK_WRITE_PROTECTED,(dp_Res2+2,a4)
- tst.b WriteProtected(a5)
- bne _ret4
- move.w #ERROR_OBJECT_NOT_FOUND,(dp_Res2+2,a4)
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a0
- bsr SearchObject
- beq _ret4
- move.l d0,a3
- move.l d1,d3
- move.w #ERROR_OBJECT_IN_USE,(dp_Res2+2,a4)
- tst.b myf_Locks(a3)
- bne _ret4
- move.l a3,a0
- bsr NotifyObject
- move.w #ERROR_OBJECT_EXISTS,(dp_Res2+2,a4)
- move.l dp_Arg3(a4),d0
- move.l dp_Arg4(a4),a0
- bsr SearchObject
- bne _ret4
- bsr SplitPath
- move.w #ERROR_DIR_NOT_FOUND,(dp_Res2+2,a4)
- move.l dp_Arg3(a4),d0
- bsr SearchPath
- beq _ret4
- move.l a3,-(sp)
- moveq #0,d2
- tst.b myf_Type(a3)
- bpl.s .D
- move.l myf_Size(a3),d2
- .D move.l d0,a3
- lea TempName(a5),a2
- bsr CreateNewObject
- move.l (sp)+,a3
- beq.s _ret4
- move.l d0,a2
- move.b myf_Type(a3),myf_Type(a2)
- bpl.s .A
- move.l a2,a1 ;rename file
- add.l d1,a1
- move.l a3,a0
- moveq #0,d0
- move.b myf_DataOffs(a3),d0
- add.l d0,a0
- move.l myf_Size(a3),d0
- sys CopyMem
- bra.s .C
- .A move.l myf_First(a3),d0 ;rename dir
- clr.l myf_First(a3)
- move.l d0,myf_First(a2)
- beq.s .C
- .E move.l d0,a0
- move.l a2,myf_Parent(a0)
- move.l myf_Link(a0),d0
- bne.s .E
- .C move.l d3,d1 ;end rename
- move.l a3,a1
- bsr DeleteObject
- beq _ret4
- move.l a2,a0
- bsr CheckNotify
- bra NoAction
-
- *******************************************************
-
- * Here are subroutines for packets that deal with Locks.
-
- ALocateObject:
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a0
- move.l dp_Arg3(a4),d2
- bsr LocateObject
- lsr.l #2,d0
- move.l d0,dp_Res1(a4)
- _ret4 rts
-
- ADupLockFromFH:
- move.l dp_Arg1(a4),d0
- bra.s DupLock
-
-
- * fixed ZERO lock -MM
-
- ADuplicateLock:
- move.l dp_Arg1(a4),d0
- lsl.l #2,d0
- DupLock movea.l d0,a0
- bne .reg ;regular non-ZERO lock
- movea.l (RootLock,a5),a0
- .reg move.l myl_Key(a0),a2
- moveq #ACCESS_READ,d2
- bsr CreateLock
- lsr.l #2,d0
- move.l d0,dp_Res1(a4)
- rts
-
- AParentFromFH:
- move.l dp_Arg1(a4),d0
- bra.s ParentD
- AParentDir:
- move.l dp_Arg1(a4),d0
- lsl.l #2,d0
- ParentD beq.s .fail ;label not used globally
- move.l d0,a0
- move.l myl_Key(a0),a2
- move.l myf_Parent(a2),d0
- beq.s .fail
- move.l d0,a2
- moveq #ACCESS_READ,d2
- bsr CreateLock
- lsr.l #2,d0
- move.l d0,dp_Res1(a4)
- .fail
- _ret5 rts
-
- AFreeLock:
- move.l dp_Arg1(a4),d0
- beq.s _ret5
- lsl.l #2,d0
- move.l d0,a1
- bsr FreeLock
- bra NoAction
-
- ASameLock:
- IFND rom
- tst.l StupIcon(a5)
- bne Unsupported
- ENDC
-
- move.l dp_Arg1(a4),a0
- add.l a0,a0
- add.l a0,a0
- move.l dp_Arg2(a4),a1
- add.l a1,a1
- add.l a1,a1
- move.l myl_Key(a0),d0
- cmp.l myl_Key(a1),d0
- bne .dif
- moveq #DOSTRUE,d1
- move.l d1,dp_Res1(a4)
- .dif rts
-
- AExamineFH:
- move.l dp_Arg1(a4),a0
- bra.s Exammi
-
- AExamineObject:
- move.l dp_Arg1(a4),a0
- add.l a0,a0
- add.l a0,a0
- Exammi move.l myl_Key(a0),a0 ;label not used globally
- move.l dp_Arg2(a4),a1
- add.l a1,a1
- add.l a1,a1
- DBUG1 txexam,a0
- move.l a1,a2
- moveq #fib_SIZEOF/4-1,d0
- .D clr.l (a2)+
- dbra d0,.D
- * Fill FileInfoBlock (fib) with infos about the object
- * Used by AExamineFH, AExamineObject and AExamineNext
- * ENTRY: a0=file, a1=fib
- ExamineObject:
- moveq #1,d0
- tst.l myf_Parent(a0)
- beq.s .C ;rootdir ?
-
- ; IFD DEBUG
- ; btst #6,myf_Type(a0)
- ; beq.s .\@D ;hidden file ?
- ; moveq #-3,d0
- ; bra.s .C
- ;.\@D ENDC
-
- moveq #-3,d0
- tst.b myf_Type(a0)
- bmi.s .C ;file ?
- moveq #2,d0 ;dir
- .C moveq #0,d1
- move.l d0,fib_DirEntryType(a1)
- move.l d0,fib_EntryType(a1)
- bpl.s .A
- move.l myf_Size(a0),d1 ;no file no size
- .A move.l a0,fib_DiskKey(a1)
- move.l d1,fib_Size(a1) ;calc size
- add.l #1023,d1
- lsr.l #8,d1
- lsr.l #2,d1
- move.l d1,fib_NumBlocks(a1)
- moveq #0,d0
- move.b (myf_Attrs,a0),d0
- ; move.b myf_Type(a0),d1
- ; btst #5,d1 ;copied ? -> A
- ; beq.s .F
- ; bset #FIBB_ARCHIVE,d0
- ;.F btst #4,d1 ;notify ? -> P
- ; beq.s .G
- ; bset #5,d0
- ;.G
- ; IFD DEBUG
- ; btst #6,d1 ;hidden ? -> H
- ; beq.s .\@J
- ; bset #7,d0
- ;.\@J tst.b myf_Locks(a0)
- ; beq.s .\@H
- ; bmi.s .\@I
- ; bset #2,d0 ;read-locked ? -> no W
- ; bra.s .\@H
- ;.\@I bset #3,d0 ;write-locked ? -> no R
- ;.\@H ENDC
-
- move.l d0,fib_Protection(a1)
- move.l (myf_Date+0,a0),fib_DateStamp+0(a1)
- move.l (myf_Date+4,a0),fib_DateStamp+4(a1)
- move.l (myf_Date+8,a0),fib_DateStamp+8(a1)
- lea myf_Name(a0),a0
- DBUG1 txexan,a0
- lea fib_FileName(a1),a1
- moveq #106,d0
- bsr CopyChar2BSTR
- bra NoAction
-
- AExamineNext:
- move.l dp_Arg1(a4),a2
- add.l a2,a2
- add.l a2,a2
- move.l dp_Arg2(a4),a1
- add.l a1,a1
- add.l a1,a1
- move.l fib_DiskKey(a1),a0
- DBUG1 txexnx,a0
- cmp.l myl_Key(a2),a0
- bne.s .A
- move.w #ERROR_OBJECT_WRONG_TYPE,(dp_Res2+2,a4)
- tst.b myf_Type(a0)
- bmi _ret6
- move.l myf_First-myf_Link(a0),a0
- bra.s .C
- .A move.l myf_Link(a0),a0
- .C move.w #ERROR_NO_MORE_ENTRIES,(dp_Res2+2,a4)
- move.l a0,d0
- beq _ret6
-
- IFND DEBUG
- btst #6,myf_Type(a0)
- bne.s .A
- ENDC
-
- bra ExamineObject
-
- ADiskInfo1:
- move.l dp_Arg1(a4),a0
- bra.s DiskInfo
- ADiskInfo2:
- move.l dp_Arg2(a4),a0
- * ENTRY: a0=buffer (BPTR)
- DiskInfo: ;label not used globally
- add.l a0,a0
- add.l a0,a0
- move.l a0,a1
- moveq #id_SIZEOF/4-1,d0
- .D clr.l (a1)+
- dbra d0,.D
-
- IFD DEBUG
- move.l NumLocks(a5),id_NumSoftErrors(a0)
- ENDC
-
- moveq #ID_VALIDATED,d0
- tst.b WriteProtected(a5)
- beq.s .C
- moveq #ID_WRITE_PROTECTED,d0
- .C move.l d0,id_DiskState(a0)
- move.l #1024,d1
- move.l d1,id_BytesPerBlock(a0)
- lsr.l #1,d1
- move.l FileSize(a5),d0
- add.l d1,d0
- lsr.l #8,d0
- lsr.l #2,d0
- move.l d0,id_NumBlocksUsed(a0)
- move.l TotalSize(a5),d0
- add.l d1,d0
- lsr.l #8,d0
- lsr.l #2,d0
- bne.s .A
- moveq #1,d0
- .A move.l d0,id_NumBlocks(a0)
- move.l #"DOS"<<8,id_DiskType(a0)
- move.l MyVolumeBPTR(a5),id_VolumeNode(a0)
- move.l RootLock(a5),id_InUse(a0)
- bra NoAction
-
- ACreateDir:
- move.w #ERROR_DISK_WRITE_PROTECTED,(dp_Res2+2,a4)
- tst.b WriteProtected(a5)
- bne.s .fail
- move.w #ERROR_OBJECT_EXISTS,(dp_Res2+2,a4)
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a0
- bsr SearchObject
- bne.s .fail
- bsr SplitPath
- move.w #ERROR_DIR_NOT_FOUND,(dp_Res2+2,a4)
- move.l dp_Arg1(a4),d0
- bsr CreatePath
- beq.s .fail
- move.l d0,a3
- lea TempName(a5),a2
- moveq #0,d2
- bsr CreateNewObject
- beq.s .fail
- move.l d0,a2
- clr.b myf_Type(a2)
- moveq #ACCESS_WRITE,d2
- bsr CreateLock
- beq.s .fail
- move.l d0,a0
- lsr.l #2,d0
- move.l d0,dp_Res1(a4)
- move.l myl_Key(a0),a0
- bsr CheckNotify
- .fail
- _ret6 rts
-
- *******************************************************
-
- * Here are subroutines that deal with Locks and Filehandles
-
- AFHfromLock:
- move.w #ERROR_OBJECT_WRONG_TYPE,(dp_Res2+2,a4)
- move.l dp_Arg2(a4),d0
- beq.s _ret7
- lsl.l #2,d0
- move.l d0,a0
- move.l myl_Key(a0),a0
- tst.b myf_Type(a0) ;do not open dirs
- bmi OpnOld
- _ret7 rts
-
- AChangeMode:
- move.w #ERROR_OBJECT_IN_USE,(dp_Res2+2,a4)
- move.l dp_Arg1(a4),d0
- move.l dp_Arg2(a4),a2
- moveq #CHANGE_FH,d1
- cmp.l d0,d1
- bne.s .A
- move.l dp_Arg1(a4),a3
- add.l a3,a3
- add.l a3,a3
- move.l fh_Arg1(a3),d0
- beq.s _ret7
- move.l d0,a2
- bra.s .C
- .A moveq #CHANGE_LOCK,d1
- cmp.l d0,d1
- bne.s _ret7
- .C move.l myl_Key(a2),a0
- move.b myf_Locks(a0),d0
- move.l dp_Arg3(a4),d2
- moveq #ACCESS_WRITE,d1
- cmp.l d1,d2
- bne.s .D
- cmp.b d0,d1
- beq.s .ok
- cmp.b #1,d0
- bne.s _ret7
- move.b d1,myf_Locks(a0)
- bra.s .ok
- .D cmp.b d0,d1
- bne.s .E
- tst.l myl_Start(a2)
- bne.s _ret7
- move.b #1,myf_Locks(a0)
- .E moveq #ACCESS_READ,d1
- .ok move.l d1,myl_Access(a2)
- bra NoAction
-
- *******************************************************
-
- * Here are subroutines for notification support
- ; dc.b 'addn'
- AAddNotify:
- move.w #ERROR_NO_FREE_STORE,(dp_Res2+2,a4)
- move.l dp_Arg1(a4),a3
- clr.l (nr_MsgCount,a3) ;only one notify per NR allowed
- moveq #myn_Name,d0
- move.l nr_FullName(a3),a0
- .C addq.l #1,d0
- tst.b (a0)+
- bne.s .C
- bsr AllocMem
- beq _ret8
- move.l d0,a2
- lea NotifyList(a5),a0
- move.l (a0),myn_Link(a2)
- move.l a2,(a0)
- move.l a3,myn_Request(a2)
- move.l nr_FullName(a3),a0
- lea myn_Name(a2),a1
- .D move.b (a0)+,(a1)+
- bne.s .D
- bsr UpNoti
-
- IFD DEBUG
- lea myn_Name(a2),a0
- DBUG4 txanoti,a2,a3,a0,d0
- ENDC
-
- btst #NRB_NOTIFY_INITIAL,(nr_Flags+3,A3) ;initial notify ?
- beq .A
- tst.l d0
- beq.s .A
- ; move.l d0,a0
- ; btst #6,myf_Type(a0) ;file really exists ?
- ; bne.s .A
- bsr SendNotify
- .A bra NoAction
-
- ARemoveNotify: movea.l (dp_Arg1,A4),A2
- move.w #ERROR_OBJECT_NOT_FOUND,(dp_Res2+2,a4)
- lea NotifyList(a5),a1
- .A move.l (a1),d0
- beq _ret8
- move.l a1,a0
- move.l d0,a1
- cmp.l myn_Request(a1),a2
- bne.s .A
- move.l myn_Link(a1),myn_Link(a0)
- DBUG2 txrnoti,a1,a2
- move.l myn_Key(a1),d0
- beq.s .D
- move.l d0,a0
- bclr #4,myf_Type(a0)
- .D moveq #myn_Name,d0
- lea myn_Name(a1),a0
- .C addq.l #1,d0
- tst.b (a0)+
- bne.s .C
- bsr FreeMem
- bra NoAction
-
- * Update myn_Key of notification list, mainly used by CheckNotify
- UpdateNotify:
- move.l a2,-(sp)
- lea NotifyList(a5),a2
- bra.s .A
- .C move.l d0,a2
- tst.l myn_Key(a2)
- bne.s .A
- bsr.s UpNoti
-
- IFD DEBUG
- beq.s .\@A
- lea myn_Name(a2),a0
- DBUG2 txunoti,a0,d0
- .\@A ENDC
-
- .A move.l (a2),d0
- bne.s .C
- move.l (sp)+,a2
- _ret8 rts
-
- * Subroutine used by UpdateNotify and AddNotify
- UpNoti lea myn_Name(a2),a0
- lea TempPath(a5),a1
- move.l #MAXPATH-1,d0
- bsr CopyChar2Char
- moveq #0,d0
- bsr SearchPath
- bne.s .A
- moveq #0,d0
- bsr CalcFullName
- .A move.l d0,myn_Key(a2)
- beq.s .D
- move.l d0,a0
- bset #4,myf_Type(a0)
- .D rts
-
- * Update notification list, check it for file/dir and parent dir
- * and notify them.
- * ENTRY: a0=file
- CheckNotify:
- move.l a0,-(sp)
-
- IFD DEBUG
- lea myf_Name(a0),a0
- DBUG1 txcnoti,a0
- ENDC
-
- bsr UpdateNotify
- move.l (sp)+,a0
-
- * Check notification list for file/dir and parent dir and notify them.
- * ENTRY: a0=file
- NotifyObject:
- cmpi.l #ACTION_END,(dp_Type,a4)
- bne \ok
- moveq #3,d0
- btst d0,(myf_Type,a0)
- beq .E
- bclr d0,(myf_Type,a0)
- bsr NotifyObj
- movea.l myf_Parent(a0),a0
- \ok bsr NotifyObj
- .E rts
-
- * Notify object in a0, only used by NotifyObject
- NotifyObj:
- movem.l a2/a3,-(sp)
- lea NotifyList(a5),a2
- bra.s .A
-
- .C move.l d0,a2
- cmp.l myn_Key(a2),a0
- bne.s .A
- move.l a0,-(sp)
- move.l myn_Request(a2),a3
- bsr SendNotify
- move.l (sp)+,a0
- .A move.l (a2),d0
- bne.s .C
- movem.l (sp)+,a2/a3
- rts
-
- * Send a Notify message or set a Notify signal
- * ENTRY: a3=NotifyRequest
- SendNotify:
- moveq #NRB_SEND_SIGNAL,d0 ;moveq #1,d0
- btst d0,nr_Flags+3(a3)
- beq.s .C
- move.l nr_Task(a3),a1
-
- IFD DEBUG
- move.l LN_NAME(a1),d0
- lea myn_Name(a2),a0
- DBUG2 txsnoti,d0,a0
- ENDC
-
- move.b nr_SignalNum(a3),d1
- asl.l d1,d0
- sys Signal
- rts
-
- .C btst #NRB_SEND_MESSAGE,nr_Flags+3(a3)
- beq .D
- moveq #NotifyMessage_SIZEOF,d0
- bsr AllocMem
- beq .D
- move.l d0,a0
- move.l d0,a1
- moveq #NotifyMessage_SIZEOF/2-1,d0
- .A clr.w (a0)+
- dbra d0,.A
- move.b #NT_MESSAGE,LN_TYPE(a1)
- movea.l NotifyPort(a5),a0
- move.l a0,MN_REPLYPORT(a1)
- move.w #NotifyMessage_SIZEOF,MN_LENGTH(a1)
- move.l #$40000000,nm_Class(a1)
- move.w #$1234,nm_Code(a1)
- move.l a3,nm_NReq(a1)
-
- IFD DEBUG
- move.l a2,-(sp)
- move.l nr_Port(a3),a0
- move.l MP_SIGTASK(a0),a0
- move.l LN_NAME(a0),a0
- lea myn_Name(a2),a2
- DBUG3 txmnoti,a1,a0,a2
- move.l (sp)+,a2
- ENDC
-
- move.l nr_Port(a3),a0
- sys PutMsg
- addq.l #1,nr_MsgCount(a3)
- ; btst #NRB_WAIT_REPLY,nr_Flags+3(a3)
- ; beq.s .D
- ; lea NotifyPort(a5),a0
- ; sys WaitPort
- ; bsr GetNotify
- .D rts
-
- *******************************************************
-
- *******************************************************
-
- * Following there are support subroutines for creating and deleting
- * objects and Locks.
-
- * Create a new file/dir
- * ENTRY: a2=name, a3=parent dir, d2=data size, a5=global data ptr, a6=exec
- * EXIT: d1=offset of data, d0=new file, Z-flag for success
- CreateNewObject:
- move.w #ERROR_DISK_FULL,(dp_Res2+2,a4)
- CreateNewObj: ;label used by SearchPath and CalcFullName
- movem.l d3/a2-a3,-(sp)
- move.l a2,a0
- moveq #myf_Name,d3
- .D addq.l #1,d3
- tst.b (a0)+
- bne.s .D
- addq.l #1,d3
- bclr #0,d3
- move.l d3,d0
- add.l d2,d0
- bsr AllocMem
- beq _ret9
- move.l d0,a1
- lea myf_First(a3),a0
- .C move.l (a0),d0
- beq.s .A
- move.l d0,a0
- bra.s .C
- .A move.l a1,(a0)
- clr.l myf_Link(a1)
- move.l a3,myf_Parent(a1)
- move.l d2,myf_Size(a1)
- add.l d2,FileSize(a5)
- bsr SetCurrentDate
- move.b #$80,myf_Type(a1)
- move.b d3,myf_DataOffs(a1)
- clr.b myf_Locks(a1)
- clr.b (myf_Attrs,a1)
- lea myf_Name(a1),a0
- .E move.b (a2)+,(a0)+
- bne.s .E
- move.l d3,d1
- move.l a1,d0
- .fail
- IFD DEBUG
- move.l d0,-(sp)
- lea myf_Name(a1),a2
- move.l myf_Size(a1),d0
- DBUG3 txcreat,a2,a1,d0
- move.l (sp)+,d0
- ENDC
-
- movem.l (sp)+,d3/a2-a3
- _ret9 rts
-
- ASetProtect: moveq #0,d2
- bra _set
- ASetDate: moveq #1,d2
- _set move.w #ERROR_DISK_WRITE_PROTECTED,(dp_Res2+2,a4)
- tst.b (WriteProtected,a5)
- bne _ret9
- move.w #ERROR_OBJECT_NOT_FOUND,(dp_Res2+2,a4)
- move.l dp_Arg2(a4),d0
- move.l dp_Arg3(a4),a0
- bsr SearchObject
- beq.s _ret9
- movea.l d0,a0 ;File
- movea.l (dp_Arg4,a4),a2
- tst.l d2
- bne .date
- move.l a2,d1
- move.b d1,(myf_Attrs,a0)
- bra .done
- .date lea (myf_Date,a1),a1
- move.l (a2)+,(a1)+
- move.l (a2)+,(a1)+
- move.l (a2)+,(a1)+
- .done bsr CheckNotify
- bra NoAction
-
-
- * Get curent DateStamp
- * ENTRY: a1=file or ZERO
-
- SetCurrentDate:
- .regs reg a0/a1/a6
- movem.l .regs,-(sp)
- move.l a1,d1
- bne .is
- lea (RootDir,a5),a1
- .is lea (myf_Date,a1),a1
- move.l a1,d1
- movea.l (DosBase,a5),a6
- sys DateStamp
- movem.l (sp)+,.regs
- rts
-
- * Delete file/dir in a1, no pred. known
- * ENTRY: a1=file a4=packet
- * EXIT: d0=success, Z-flag
- DeleteObj:
- move.w #ERROR_OBJECT_NOT_FOUND,(dp_Res2+2,a4)
- move.l myf_Parent(a1),a0
- move.l myf_First(a0),d0
- sub.l a0,a0
- .C move.l a0,d1
- move.l d0,a0
- tst.l d0
- beq DelErr
- move.l myf_Link(a0),d0
- cmp.l a1,a0
- bne.s .C
-
- * Delete file/dir in a1 with pred. known
- * ENTRY: a1=file d1=pred a4=packet
- DeleteObject:
- move.l d2,-(sp)
- moveq #0,d0
- move.w #ERROR_OBJECT_IN_USE,(dp_Res2+2,a4)
- tst.b myf_Locks(a1)
- bne.s .fail
- tst.b myf_Type(a1)
- bmi.s .C
- move.w #ERROR_DIRECTORY_NOT_EMPTY,(dp_Res2+2,a4)
- tst.l myf_First(a1) ;check if dir is empty
- bne.s .fail
- .C move.l myf_Link(a1),d2 ;rearrange links
- move.l d1,a0
- tst.l d1
- bne.s .A
- move.w #ERROR_OBJECT_WRONG_TYPE,(dp_Res2+2,a4)
- move.l myf_Parent(a1),d1
- beq.s .fail ;do not delete root
- move.l d1,a0
- lea myf_First-myf_Link(a0),a0
- .A move.l d2,myf_Link(a0)
- DBUG1 txdel,a1
- lea NotifyList(a5),a0
- bra.s .D
- .E move.l d0,a0
- cmp.l myn_Key(a0),a1
- bne.s .D
- clr.l myn_Key(a0) ;check notifications
- .D move.l (a0),d0
- bne.s .E
- ; moveq #0,d0 ;free memory
- move.b myf_DataOffs(a1),d0
- move.l myf_Size(a1),d1
- add.l d1,d0
- sub.l d1,FileSize(a5)
- bsr FreeMem
- moveq #1,d0
- .fail move.l (sp)+,d2
- DelErr tst.l d0 ;label not used globally
- rts
-
- * Create lock on file/dir given by name
- * Must preserve a3
- * ENTRY: d0=BPTR parent lock, a0=name (BSTR), d2=access mode
- * EXIT: d0=APTR lock, Z-flag
- LocateObject:
- move.w #ERROR_OBJECT_NOT_FOUND,(dp_Res2+2,a4)
- move.l d0,d3
- bsr SearchObject
- bne.s .A
- moveq #ACCESS_WRITE,d0
- sub.l d2,d0
- beq LOfail2
- move.l d3,d0
- bsr CalcFullName
- beq LOfail2
- .A movea.l d0,a2
-
- * Create lock on file/dir given by key
- * ENTRY: a2=file, d2=access mode
- * EXIT: d0=success, Z-flag
- CreateLock:
- moveq #0,d0
- move.w #ERROR_OBJECT_IN_USE,(dp_Res2+2,a4)
- lea myf_Locks(a2),a0
- moveq #ACCESS_WRITE,d1
- cmp.l d1,d2
- bne.s .A
- tst.b (a0)
- bne.s LOfail
- move.b d1,(a0)
- bra.s .C
- .A tst.b (a0)
- bmi.s LOfail
- addq.b #1,(a0)
- .C move.w #ERROR_NO_FREE_STORE,(dp_Res2+2,a4)
- move.l #myl_SIZEOF,d0
- bsr AllocMem
- beq.s LOfail
- move.l d0,a0
- clr.l (a0)+ ;clr.l myl_Link(a0)
- move.l a2,(a0)+ ;myl_Key(a0)
- move.l d2,(a0)+ ;myl_Access(a0)
- move.l MyMsgPort(a5),(a0)+ ;myl_Task(a0)
- move.l MyVolumeBPTR(a5),(a0)+ ;myl_Volume(a0)
- clr.l (a0)+ ;myl_Pos(a0)
- clr.l (a0)+ ;myl_Data(a0)
- clr.l (a0)+ ;myl_Start(a0)
- clr.l (a0)+ ;myl_Block(a0)
- clr.l (a0)+ ;myl_BlockPos(a0)
- clr.l (a0)+ ;myl_Size(a0)
- clr.b (a0) ;myl_Mode(a0)
- addq.l #1,NumLocks(a5)
- LOfail
- IFD DEBUG
- move.l d0,d1
- lsr.l #2,d1
- lea myf_Name(a2),a0
- DBUG3 txlock,a0,d1,d2
- ENDC
-
- LOfail2 tst.l d0
- rts
-
- * Free lock in a1
- * ENTRY: a1=lock (APTR)
- FreeLock:
- ; move.w #ERROR_UNLOCK_ERROR,(dp_Res2+2,a4)
-
- IFD DEBUG
- move.l a1,d0
- lsr.l #2,d0
- DBUG1 txulock,d0
- ENDC
-
- move.l myl_Key(a1),a0
- tst.b myf_Locks(a0)
- beq.s .A
- bmi.s .D
- subq.b #1,myf_Locks(a0)
- bra.s .A
- .D clr.b myf_Locks(a0)
- .A move.l #myl_SIZEOF,d0
- bsr FreeMem
- subq.l #1,NumLocks(a5)
- rts
-
- *******************************************************
-
- *******************************************************
-
- * Support routines for lower level memory management
-
- * ENTRY: d0=size
- * EXIT: d0=memory/Z flag
- AllocMem:
- add.l d0,TotalSize(a5)
- move.l MyMemPool(a5),d1
- beq.s .A
- move.l d1,a0
- sys AllocPooled
- tst.l d0
- rts
- .A moveq #MEMF_PUBLIC,d1
- add.l #MN_SIZE,d0
- sys AllocVec
- tst.l d0
- beq .ret
- lea (MyML,a5),a0 ;add alloc to our list
- movea.l d0,a1
- move.l (a0),d1
- move.l a1,(a0)
- movem.l d1/a0,(a1)
- move.l d1,a0
- move.l a1,(LN_PRED,a0)
- add.l #MN_SIZE,d0
- .ret rts
-
- * ENTRY: d0=size, a1=address
- FreeMem:
- sub.l d0,TotalSize(a5)
- move.l MyMemPool(a5),d1
- beq.s .A
- move.l d1,a0
- sys FreePooled
- rts
- .A suba.w #MN_SIZE,a1
- _free move.l a1,d1
- REMOVE ;remove alloc from our list
- movea.l d1,a1
- sys FreeVec
- rts
-
- * Copy BSTR in a0 to string in a1, d0=maxlength without 0
- CopyBSTR2Char:
- add.l a0,a0
- add.l a0,a0
- moveq #0,d1
- move.b (a0)+,d1
- MIN d0,d1,D
- bra.s .C
- .A move.b (a0)+,(a1)+
- .C dbra d1,.A
- clr.b (a1)
- rts
-
- * Copy string in a0 to BSTR in a1, d0=maxlength without 0
- * EXIT: d0=BPTR
- CopyChar2BSTR:
- moveq #-1,d1
- addq.l #1,a1
- .A addq.l #1,d1
- cmp.l d0,d1
- bhs.s .C
- move.b (a0)+,(a1)+
- bne.s .A
- subq.l #1,a1
- .C clr.b (a1)
- sub.l d1,a1
- subq.l #1,a1
- move.b d1,(a1)
- move.l a1,d0
- lsr.l #2,d0
- rts
-
- CopyChar2Char:
- * Copy string in a0 to string in a1, d0=maxlength without 0
- .C move.b (a0)+,(a1)+
- beq.s .A
- subq.l #1,d0
- bne.s .C
- .A rts
-
-
- *******************************************************
-
- *******************************************************
-
- * Subroutines for path string handling following
-
- * Same as SearchObject, but deletes hidden files
- * ENTRY: a0=filename (BSTR), d0=lock on dir
- * EXIT: d0=ptr to file, Z-flag, d1=previous file, TempPath=name
- ;DelSearchObject
- ; bsr SearchObject
- ; beq.s .A
- ; move.l d0,a1
- ; btst #6,myf_Type(a1)
- ; beq.s .A
- ; bsr DeleteObject ;delete hidden file
- ; moveq #0,d0
- ;.A tst.l d0
- ; rts
-
- * Same as SearchPath, but creates the path if not existent
- * ENTRY: TempPath=dirname, d0=lock on dir
- * EXIT: d0=ptr to file, Z-flag, d1=previous file
- CreatePath:
- moveq #1,d1
- bra.s SearchP
-
- * Look for object with path
- * ENTRY: a0=filename (BSTR), d0=lock on dir
- * EXIT: d0=ptr to file, Z-flag, d1=previous file, TempPath=name
- SearchObject:
- move.l d0,-(sp)
- lea TempPath(a5),a1
- move.l #MAXPATH-1,d0
- bsr CopyBSTR2Char
- move.l (sp)+,d0
-
- * Same as SearchObject, but name is already copied to TempPath
- * ENTRY: TempPath=dirname, d0=lock on dir
- * EXIT: d0=ptr to file, Z-flag, d1=previous file
- SearchPath:
- moveq #0,d1
- SearchP movem.l d2-d7/a2-a4,-(sp) ;label not used globally
- move.l d1,d7
- lea TempPath(a5),a0
- .A move.b (a0)+,d1
- beq .B
- cmp.b #":",d1 ;skip volume name
- bne .A
- .B tst.l d0
- bne .C
- move.l (RootLock,a5),d0
- lsr.l #2,d0
- .C tst.b d1
- bne .D
- lea TempPath(a5),a0
- .D lsl.l #2,d0 ;use root or locked dir
- movea.l d0,a2
- move.l (myl_Key,a2),a1 ;dir represented by lock
-
- * label not used
- expand
-
- * label not used
- * ENTRY: a0=Name, a1=parent dir; mind SP !
- * EXIT: d0=ptr to file, Z-flag, d1=previous file
- SearchName:
- .A moveq #0,d0
- .D cmp.b #"/",(a0) ;parent dir when starting with /
- bne.s .H
- move.l myf_Parent(a1),d2
- beq.s .fail
- move.l d2,a1
- addq.l #1,a0
- bra.s .D
- .H tst.b (a0) ;check for empty string
- beq.s .G
- move.l a0,a4
- moveq #0,d3
- .C addq.l #1,d3 ;look for / or end
- tst.b (a4)
- beq.s .E
- cmp.b #":",(a4)
- beq.s .fail
- cmp.b #"/",(a4)+
- bne.s .C
- .E tst.b myf_Type(a1)
- bmi.s .fail
- move.l a1,d2
- bsr SearchEntry ;search in dir
- bne.s .F
- tst.l d7 ;check for CreatePath
- beq.s .G
- movem.l d1-d3/a0/a2-a4,-(sp)
- move.l d2,a3
- move.l a0,a2
- move.l a0,a4
- subq.l #1,d3
- add.l d3,a4
- move.b (a4),d3
- clr.b (a4)
- moveq #0,d2
- bsr CreateNewObj ;create new dir
- move.b d3,(a4)
- ; move.l d0,a1
- movem.l (sp)+,d1-d3/a0/a2-a4
- tst.l d0
- beq.s .I
- clr.b myf_Type(a1)
- .F move.l a4,a0
- bra.s .A ;continue looking for / or end
- .G move.l a1,d0
- .fail
- IFD DEBUG
- lea TempPath(a5),a0
- moveq #0,d2
- tst.l d0
- beq.s .\@I
- move.b myf_Type(a1),d2
- .\@I DBUG3 txfnd,a0,d0,d2
- ENDC
-
- .I movem.l (sp)+,d2-d7/a2-a4
- tst.l d0
- rts
-
- * Look for object in dir
- * ENTRY: a0=file/dir name, a1=ptr to dir, d3=length of name
- * EXIT: a1=ptr to file or 0, Z-flag
- SearchEntry:
- moveq #0,d5
- moveq #0,d6
- move.l myf_First(a1),d0
- sub.l a1,a1
- .C move.l a1,d1
- move.l d0,a1
- tst.l d0
- beq.s .fail
- move.l myf_Link(a1),d0
- lea myf_Name(a1),a2
- move.l a0,a3
- move.l d3,d4
- bra.s .E
- .A move.b (a2)+,d5
- move.b CharTable(a5,d5.l),d5
- move.b (a3)+,d6
- move.b CharTable(a5,d6.l),d6
- cmp.b d5,d6
- bne.s .C
- .E subq.l #1,d4
- bne.s .A
- tst.b (a2)
- bne.s .C
-
- IFD DEBUG
- lea myf_Name(a1),a3
- DBUG1 txentry,a3
- ENDC
-
- .fail move.l a1,d0
- rts
-
- * Splits path with file into path=TempPath and file=TempName
- * ENRTY: TempPath=file with path
- * EXIT: TempPath=path, TempName=file
- SplitPath
- move.l a2,-(sp)
- lea TempPath(a5),a0
- move.l a0,a1
- .A tst.b (a0)+
- bne.s .A
- .D cmp.b #"/",-(a0)
- beq.s .C
- cmp.b #":",(a0)
- beq.s .C
- cmp.l a0,a1
- bne.s .D
- move.l a0,a1
- bra.s .G
- .C move.l a0,a1
- addq.l #1,a1
- .G lea TempName(a5),a2
- .E move.b (a1)+,(a2)+
- bne.s .E
- cmp.b #":",(a0)
- bne.s .F
- addq.l #1,a0
- .F clr.b (a0)
- move.l (sp)+,a2
-
- IFD DEBUG
- lea TempPath(a5),a0
- lea TempName(a5),a1
- DBUG2 txsplit,a0,a1
- ENDC
-
- rts
-
- * Evaluate full path name of object
- * Only used by CalcFullName
- * ENTRY: a1=object
- * EXIT: a0=full name (root name not included) in TempPath
- GetFullName:
- move.l d2,-(sp)
- lea TempPath+MAXPATH+MAXNAME-1(a5),a0
- clr.b (a0)
- move.w #MAXPATH+MAXNAME-1,d2
- .A move.l myf_Parent(a1),d0
- beq.s .ok
- lea myf_Name(a1),a1
- moveq #-1,d1
- .C addq.l #1,d1
- tst.b (a1)+
- bne.s .C
- subq.l #1,a1
- sub.w d1,d2
- bmi.s .ok
- tst.b (a0)
- beq.s .D
- move.b #"/",-(a0)
- subq.w #1,d2
- bra.s .D
- .E move.b -(a1),-(a0)
- .D dbra d1,.E
- move.l d0,a1
- bra.s .A
- .ok move.l (sp)+,d2
- rts
-
- * Create dir and copy file from ENVARC: if possible
- * Only used by LocateObject and UpNoti
- * ENTRY: TempPath=name, d0=BPTR parent lock
- * EXIT: d0=file or ZERO
- CalcFullName:
- .regs reg d2-d7/a2-a4
- movem.l .regs,-(sp)
- moveq #0,d7 ;d7=return code
- tst.b WriteProtected(a5)
- bne .fail
-
- IFND rom
- tst.l StupNocopy(a5)
- bne .fail
- ENDC
-
- move.l d0,d2 ;BPTR to parent lock
- bsr SearchPath
- bne .found
- move.l d2,d0
- bsr CreatePath
- beq .fail
- .found move.l d0,a1
- move.l d0,a2
- bsr GetFullName
- DBUG1 txfull,a0
- lea TempPath(a5),a1
- move.l #MAXPATH-2,d0
- bsr CopyChar2BSTR
- move.l d0,d5 ;d5=BSTR full name
- lea (MyMsg,a5),a1
- movem.l d5/a2,(MN_SIZE,a1)
- movea.l (DosPort,a5),a0
- sys PutMsg
- movea.l (PacketPort,a5),a0
- sys WaitPort
- movea.l (PacketPort,a5),a0
- sys GetMsg
- movea.l d0,a0
- move.l (MN_SIZE,a0),d7
- beq .fail1
- move.l (MN_SIZE+4,a0),(dp_Res2,a4)
- movea.l d7,a1
- lea (MyFIB,a5),a0
- move.b (fib_Protection+3,a0),(myf_Attrs,a1)
- lea (fib_DateStamp,a0),a0
- lea (myf_Date,a1),a1
- move.l (a0)+,(a1)+
- move.l (a0)+,(a1)+
- move.l (a0)+,(a1)+
- cmpa.l d7,a2 ;if dir they're equal
- beq .ok
- .fail1 move.l (dp_Res2,a4),d2
- move.l a2,a1
- bsr DeleteObj
- move.l d2,(dp_Res2,a4)
- tst.l d7
- beq .fail
- .ok bsr UpdateNotify
- .fail move.l d7,d0
- movem.l (sp)+,.regs
- _perr rts
-
- * code of special sub-process for synchronous dos calls follows -MM
-
- procc: movea.l (4).w,a6
- sys CreateMsgPort
- move.l d0,d7
- beq _perr
- move.l #1<<15,d0 ;wait for CTRL-F
- sys Wait
- suba.l a1,a1
- sys FindTask
- movea.l d0,a4
- movea.l (TC_Userdata,a4),a5
- lea (pr_MsgPort,a4),a4
- move.l d7,(DosPort,a5)
- movea.l (PacketPort,a5),a0
- moveq #1,d0
- move.b (MP_SIGBIT,a0),d1
- movea.l (MP_SIGTASK,a0),a1
- lsl.l d1,d0
- sys Signal ;signal parent we're ready
-
- .mloop movea.l d7,a0
- sys WaitPort
- movea.l d7,a0
- sys GetMsg
- movea.l d0,a3
- lea (MN_SIZE,a3),a0
- move.l (a0)+,d4 ;BSTR of full object's name
- beq .quit
- movea.l (a0),a2 ;object
-
- *-----------------------------------------------------
- * perform synchronous DOS IO
- * in: d4=BSTR of full object's name, a2 - object
- * out: d0=new object or NULL, d5=NULL if read successfull, dp_Res2 otherwise
-
- .regs reg d7/a3/a6
- movem.l .regs,-(sp)
- movea.l (DosBase,a5),a6
- moveq #0,d6
- moveq #0,d7
-
- .loop lea (envarc,pc),a0
- move.l a0,d1
- move.l d6,d2
- sys GetDeviceProc
- move.l d0,d6
- beq .fail
- move.l d6,a4
- move.l (dvp_Port,a4),d1 ;port
- moveq #ACTION_LOCATE_OBJECT,d2 ;action
- move.l (dvp_Lock,a4),d3 ;arg1
- moveq #ACCESS_READ,d5 ;arg3
- sys DoPkt
- move.l d0,d3 ;d3=lock on object
- beq .loop ;not found
-
- move.l d3,d1
- lea (MyFIB,a5),a3
- move.l a3,d2
- sys Examine
- move.l d0,-(sp)
- move.l d3,d1
- sys UnLock
- move.l (sp)+,d0
- beq .fail1
- moveq #0,d5
- tst.l (fib_DirEntryType,a3)
- bpl .ok
-
- move.l (dvp_Port,a4),d1 ;port
- move.l #ACTION_FINDINPUT,d2 ;action
- move.l d4,d5 ;arg3
- move.l (dvp_Lock,a4),d4 ;arg2
- lea (MyFH,a5),a0
- move.l a0,d3
- lsr.l #2,d3 ;arg1
- sys DoPkt
- tst.l d0
- beq .fail1
- movem.l a2/a3/a6,-(sp)
- move.l (fib_Size,a3),d2
- movea.l (myf_Parent,a2),a3
- lea (myf_Name,a2),a2
- movea.l (ExecBase,a5),a6
- bsr CreateNewObj
- movem.l (sp)+,a2/a3/a6
- beq.s .fail2
- move.l d0,d4
- add.l d1,d4 ;arg2 (buffer)
- movea.l d0,a2
- move.b #$a0,(myf_Type,a2)
- move.l (fib_Size,a3),d5 ;arg3 (size to read)
- moveq #ACTION_READ,d2 ;action
- lea (MyFH,a5),a0
- move.l (fh_Arg1,a0),d3 ;arg1
- move.l (dvp_Port,a4),d1 ;port
- sys DoPkt
- sub.l d0,d5
- beq .fail2
- move.l d1,d5 ;secondary result
- .fail2 move.l (dvp_Port,a4),d1 ;port
- move.l #ACTION_END,d2 ;action
- sys DoPkt
- .ok move.l a2,d7
- .fail1 move.l d6,d1
- sys FreeDeviceProc
- .fail move.l d7,d0
- movem.l (sp)+,.regs
- *-----------------------------------------------------
-
- move.l d0,(MN_SIZE,a3) ;primary result
- move.l d5,(MN_SIZE+4,a3) ;secondary result
- movea.l a3,a1
- sys ReplyMsg
- bra .mloop
-
- .quit movea.l d7,a0
- sys DeleteMsgPort
- movea.l a3,a1
- sysj ReplyMsg
-
- *******************************************************
-
- _romtag dc.w $4AFC
- dc.l _romtag ;rt_MatchTag
- dc.l _end ;rt_EndSkip
- dc.b RTF_AFTERDOS ;rt_Flags
- dc.b 37 ;rt_Version
- dc.b 0 ;rt_Type
- dc.b -124 ;rt_Pri
- dc.l _name ;rt_Name
- dc.l _id ;rt_IdString
- dc.l _init ;rt_Init
-
- _name dc.b 'env-handler'
- _ns=*-_name
- dc.b 0
- dc.b '$VER: '
- _id dc.b 'HappyENV-Handler '
-
- ifnd test
- $VER
- elseif
- dc.b 'TEST'
- endc
-
- dc.b ' ('
- ifnd test
- fdate
- else
- mydate
- endc
- dc.b ')',10,13,0
-
-
- _init movem.l a2/d6/d7,-(sp)
- moveq #0,d7
- moveq #DeviceNode_SIZEOF+8+13,D0
- move.l #MEMF_PUBLIC|MEMF_CLEAR,D1
- sys AllocMem
- tst.l D0
- beq .skip
- movea.l D0,A2
- lea (DeviceNode_SIZEOF,a2),a1 create BCPL 'ENV' string (5 bytes)
- moveq #3,d0
- lea (envarc,pc),a0
- bsr CopyChar2BSTR
- move.l d0,(dn_Name,a2)
- lea (DeviceNode_SIZEOF+8,a2),a1 create BCPL handler string (11 bytes)
- lea (_name,pc),a0
- moveq #_ns,d0
- bsr CopyChar2BSTR
- move.l d0,(dn_Handler,a2)
-
- IFD rom
- moveq #OLTAG_EXPANSION,d0
- sys TaggedOpenLibrary
- ELSE
- lea (_expn,pc),a1
- moveq #37,d0
- sys OpenLibrary
- ENDC
-
- move.l d0,d6
- beq.b .fail
- exg d6,a6
- lea (start,pc),a0
- subq.l #4,a0
- move.l a0,d0 ;init
-
- IFND rom
- move.l (a0),d1
- beq .ns
- addq.l #1,d1
- move.l d1,(dn_Startup,a2)
- ENDC
-
- .ns asr.l #2,d0
- move.l d0,(dn_SegList,a2)
- move.w #2000,(dn_StackSize+2,A2)
- not.l (dn_GlobalVec,A2) ;globvec -1
- moveq #5,D0
- move.l D0,(dn_Priority,a2)
- moveq #-128,D0 ;bootpri = do not boot at all
- moveq #0,D1
- suba.l a1,a1
- movea.l a2,a0
- sys AddBootNode
- move.l d0,d7
- .fn movea.l a6,a1
- movea.l d6,A6
- sys CloseLibrary
- tst.l d7
- bne .skip
- .fail movea.l a2,a1
- moveq #DeviceNode_SIZEOF+8+13,d0
- sys FreeMem
- .skip move.l d7,d0
- movem.l (sp)+,a2/d6/d7
- rts
- _end
-
- *******************************************************
-
- *******************************************************
-
- * Debug output support subroutines and strings following
-
- IFD DEBUG
-
- * Output one character
- RawHook move.l a6,-(sp)
- move.l 4.w,a6
- jsr _LVORawPutChar(a6)
- move.l (sp)+,a6
- rts
-
- * Wait for CTRL-C signal
- wait_c:
- movem.l d0-d1/a0-a1,-(sp)
- moveq #0,d0
- moveq #0,d1
- bset #12,d1
- jsr _LVOSetSignal(a6)
- moveq #0,d0
- bset #12,d0
- jsr _LVOWait(a6) ;wait for CTRL-C
- movem.l (sp)+,d0-d1/a0-a1
- rts
-
- IFD VERBOSE
- txstart dc.b "Handler started, A5=$%lx.",10,0
- txend dc.b "Handler ended, FileSize=%ld, TotalSize=%ld, Locks=%ld..",10,0
- txcopy dc.b "Copyfrom=$%lx.",10,0
- txpack dc.b "Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx, Task=%s.",10,0
- txres dc.b "Result1=$%lx, Result2=%ld.",10,0
- txpkt dc.b " Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
- txerr1 dc.b " %ld: Unknown Action.",10,0
-
- txopeno dc.b " Oldopen lock=$%lx.",10,0
- txopenn dc.b " Newopen lock=$%lx.",10,0
- txcreat dc.b " Created file %s=$%lx size=%ld.",10,0
- txread dc.b " Read %ld of %ld bytes, pos=%ld.",10,0
- txwrite dc.b " Wrote %ld bytes, pos=%ld, size=%ld.",10,0
- txwins dc.b " Inserted %ld bytes at %ld.",10,0
- txchng dc.b " Changed mode, pos=%ld, size=%ld.",10,0
- txseek dc.b " Seeked, filepos=%ld.",10,0
- txdel dc.b " Deleted $%lx.",10,0
-
- txlock dc.b " Locked %s=$%lx mode %ld.",10,0
- txulock dc.b " Unlocked $%lx.",10,0
- txexam dc.b " Examined file=$%lx.",10,0
- txexnx dc.b " Examined next file=$%lx.",10,0
- txfnd dc.b " Found %s=$%lx type=$%lx.",10,0
- txentry dc.b " Found entry %s.",10,0
- txsplit dc.b " Splitted ->%s,%s.",10,0
- txfull dc.b " Full name: %s.",10,0
- txexp dc.b " Expanded path to %s.",10,0
-
- txanoti dc.b " Added noti $%lx->$%lx on %s key=$%lx.",10,0
- txrnoti dc.b " Removed noti $%lx->$%lx.",10,0
- txcnoti dc.b " Checking noti on %s.",10,0
- txunoti dc.b " Updated noti on %s key=$%lx.",10,0
- txsnoti dc.b " Sent signal to %s for %s.",10,0
- txmnoti dc.b " Sent message $%lx to %s for %s.",10,0
- txgnoti dc.b " Got message $%lx.",10,0
- ENDC
-
- IFND VERBOSE
- txstart dc.b "Handler started, A5=$%lx.",10,0
- txend dc.b "Handler ended, FileSize=%ld, TotalSize=%ld, Locks=%ld.",10,0
- txcopy dc.b "Copyfrom=$%lx.",10,0
- txpack dc.b "Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx, Task=%s.",10,0
- txres dc.b "Result1=$%lx, Result2=%ld.",10,0
- txpkt dc.b 0;" Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
- txerr1 dc.b " %ld: Unknown Action.",10,0
- txargs dc.b "Args: $%lx, $%lx, $%lx, $%lx.",10,0
-
- txopeno dc.b " Oldopen lock=$%lx.",10,0
- txopenn dc.b " Newopen lock=$%lx.",10,0
- txcreat dc.b " Created file %s=$%lx size=%ld.",10,0
- txread dc.b 0;" Read %ld of %ld bytes, pos=%ld.",10,0
- txwrite dc.b 0;" Wrote %ld bytes, pos=%ld, size=%ld.",10,0
- txwins dc.b 0;" Inserted %ld bytes at %ld.",10,0
- txchng dc.b 0;" Changed mode, file=$%lx, pos=%ld, size=%ld.",10,0
- txsize dc.b 0;" Changed size, file=$%lx, oldsize=%ld, newsize=%ld.",10,0
- txseek dc.b 0;" Seeked, filepos=%ld.",10,0
- txdel dc.b " Deleted $%lx.",10,0
-
- txlock dc.b 0;" Locked %s=$%lx mode %ld.",10,0
- txulock dc.b 0;" Unlocked $%lx.",10,0
- txexam dc.b 0;" Examined file=$%lx.",10,0
- txexan dc.b 0;" Examined %s.",10,0
- txexnx dc.b 0;" Examined next file=$%lx.",10,0
- txfnd dc.b 0;" Found %s=$%lx type=$%lx.",10,0
- txentry dc.b 0;" Found entry %s.",10,0
- txsplit dc.b 0;" Splitted ->%s,%s.",10,0
- txfull dc.b 0;" Full name: %s.",10,0
- txexp dc.b " Expanded path to %s.",10,0
-
- txanoti dc.b " Added noti $%lx->$%lx on %s key=$%lx.",10,0
- txrnoti dc.b " Removed noti $%lx->$%lx.",10,0
- txcnoti dc.b 0;" Checking noti on %s.",10,0
- txunoti dc.b 0;" Updated noti on %s key=$%lx.",10,0
- txsnoti dc.b 0;" Sent signal to %s for %s.",10,0
- txmnoti dc.b 0;" Sent message $%lx to %s for %s.",10,0
- txgnoti dc.b 0;" Got message $%lx.",10,0
- ENDC
-
- ENDC
-